package city.spring.modules.material.controller;

import city.spring.modules.material.entity.MaterialQuantityEntity;
import city.spring.modules.material.entity.MaterialinventoryMaterialExtEntity;
import city.spring.modules.material.repository.MaterialinventoryMaterialExtRepository;
import city.spring.modules.material.service.MaterialInventoryService;
import city.spring.modules.material.service.MaterialQuantityService;
import city.spring.modules.material.service.MaterialinventoryMaterialExtService;
import city.spring.modules.material.vo.MaterialinventoryMaterialVO;
import city.spring.utils.MyBatisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Controller：物资盘点计划与物资关系表
 *
 * @author 谢金婷
 * @date 2020-07-27 09:44:32
 */
@RestController
@RequestMapping("/materialinventory/{inventoryId}/material")
public class MaterialinventoryMaterialExtController extends ApiController {
    private final MaterialinventoryMaterialExtService materialinventoryMaterialExtService;
    private final MaterialinventoryMaterialExtRepository materialinventoryMaterialExtRepository;
    private final MaterialInventoryService materialInventoryService;
    private final MaterialQuantityService materialQuantityService;
    /**
     * 实体类可排序字段
     */
    private final List<SFunction<MaterialinventoryMaterialExtEntity, ?>> entityOrderFields;

    public MaterialinventoryMaterialExtController(MaterialinventoryMaterialExtService materialinventoryMaterialExtService, MaterialinventoryMaterialExtRepository materialinventoryMaterialExtRepository, MaterialInventoryService materialInventoryService, MaterialQuantityService materialQuantityService) {
        this.materialinventoryMaterialExtService = materialinventoryMaterialExtService;
        this.materialinventoryMaterialExtRepository = materialinventoryMaterialExtRepository;
        this.materialInventoryService = materialInventoryService;
        this.materialQuantityService = materialQuantityService;
        entityOrderFields = new ArrayList<>();
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getId);
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getMaterialinventoryId);
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getStorehouseId);
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getMaterialId);
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getQuantity);
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getUnitmeasurement);
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getInventoryquantity);
        entityOrderFields.add(MaterialinventoryMaterialExtEntity::getProfitAndLoss);
    }

    @ModelAttribute
    public void getInventoryId(@PathVariable String inventoryId) {
        if (inventoryId == null) {
            throw new RuntimeException("盘点计划ID必须不为空");
        }
    }

    /**
     * 获取全部的 <strong>物资盘点计划与物资关系表</strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault Pageable pageable, MaterialinventoryMaterialExtEntity entity) {
        LambdaQueryChainWrapper<MaterialinventoryMaterialExtEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }

//    /**
//     * 分页获取 <strong>物资盘点计划与物资关系表</strong> 列表
//     *
//     * @param pageable 分页参数信息
//     */
//    @GetMapping
//    public Object list(@PageableDefault Pageable pageable, MaterialinventoryMaterialExtEntity entity) {
//        LambdaQueryChainWrapper<MaterialinventoryMaterialExtEntity> lambdaQuery = buildLambdaQuery(entity);
//        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
//        Page<MaterialinventoryMaterialExtEntity> page = lambdaQuery.page(MyBatisUtils.toPage(pageable, false));
//        return success(page);
//    }

    /**
     * 获取盘点计划所有人员列表
     *
     * @param inventoryId 盘点计划ID
     */
    @GetMapping
    public Object list(@PathVariable String inventoryId) {
        return success(materialinventoryMaterialExtRepository.getInventoryMaterials(inventoryId));
    }

    /**
     * 获取需要校正的盘点物资
     * @param inventoryId
     * @return
     */
    @GetMapping("/getNeedInventoryList")
    public Object getNeedInventoryList(@PathVariable String inventoryId) {
        return success(materialinventoryMaterialExtRepository.getNeedInventoryMaterials(inventoryId));
    }

//    /**Material
//     * 获取一个 <strong>物资盘点计划与物资关系表</strong>
//     *
//     * @param id 主键ID
//     */
//    @GetMapping("{id}")
//    public Object info(@PathVariable String id) {
//        return success(materialinventoryMaterialExtService.getById(id));
//    }

    /**
     * 获取方案的一个人员信息
     *
     * @param inventoryId 方案ID
     * @param extId       关联ID
     * @return
     */
    @GetMapping("{extId}")
    public Object getInfo(@PathVariable String inventoryId, @PathVariable Long extId) {
        return success(materialinventoryMaterialExtRepository.getInventoryMaterial(inventoryId, extId));
    }

//    /**
//     * 添加一个 <strong>物资盘点计划与物资关系表</strong>
//     *
//     * @param entity 修改后的信息
//     */
//    @PostMapping
//    public Object add(@RequestBody MaterialinventoryMaterialExtEntity entity) {
//        materialinventoryMaterialExtService.saveMaterialinventoryMaterialExt(entity);
//
//        HttpHeaders headers = new HttpHeaders();
//        headers.add(HttpHeaders.LOCATION, String.valueOf(entity.getId()));
//        return new ResponseEntity<>(headers, HttpStatus.CREATED);
//    }

    /**
     * 给方案添加多个人员信息
     *
     * @param inventoryId 方案ID
     * @param materials   所添加的人员信息列表
     * @return
     */
    @PostMapping
    public Object addAll(@PathVariable String inventoryId, @RequestBody List<MaterialinventoryMaterialExtEntity> materials) {
        // 查出已有的数据
        List<MaterialinventoryMaterialVO> dbMaterials = materialinventoryMaterialExtRepository.getInventoryMaterials(inventoryId);
        // 数据库已经存在的班次列表
        Set<String> dbMaterialIdsSet = dbMaterials.stream()
                .map(MaterialinventoryMaterialExtEntity::getMaterialId)
                .collect(Collectors.toSet());
        // 过滤掉已经存在数据库的数据
        List<MaterialinventoryMaterialExtEntity> needSaveMaterials = materials.stream()
                .filter(item -> {
                    item.setMaterialinventoryId(inventoryId);
                    item.setInventorydate(new Date());
                    MaterialQuantityEntity materialQuantity = materialQuantityService.getByMaterialId(item.getMaterialId());
                    item.setProfitAndLoss(item.getInventoryquantity().subtract(materialQuantity.getQuantity()));
                    String materialId = item.getMaterialId();
                    // 过滤出不存在数据库中的数据
                    return materialId != null && !dbMaterialIdsSet.contains(materialId);
                }).collect(Collectors.toList());
        if (!needSaveMaterials.isEmpty()) {
            materialinventoryMaterialExtService.saveBatch(needSaveMaterials);
        }

        // 实时更新库存，保存后更新库存数量
        for (MaterialinventoryMaterialExtEntity needsave : needSaveMaterials) {
            MaterialQuantityEntity materialQuantityEntity = materialQuantityService.getByMaterialIdAndStorehouseId(needsave.getMaterialId(), needsave.getStorehouseId());
            // 更新 库存数量=实盘数量
            materialQuantityEntity.setQuantity(needsave.getInventoryquantity());
            // 更新 总金额
            materialQuantityEntity.setTotal(needsave.getInventoryquantity().multiply(materialQuantityEntity.getUnitprice()));
            materialQuantityService.lambdaUpdate()
                    .set(MaterialQuantityEntity::getQuantity, materialQuantityEntity.getQuantity())
                    .set(MaterialQuantityEntity::getTotal, materialQuantityEntity.getTotal())
                    .eq(MaterialQuantityEntity::getId, materialQuantityEntity.getId())
                    .update();
        }

        return success(null);

    }

//    /**
//     * 修改一个 <strong>物资盘点计划与物资关系表</strong>
//     *
//     * @param id     主键ID
//     * @param entity 修改后的信息
//     */
//    @PutMapping("{id}")
//    public Object update(@PathVariable String id, @RequestBody MaterialinventoryMaterialExtEntity entity) {
//        entity.setId(id);
//        materialinventoryMaterialExtService.updateMaterialinventoryMaterialExt(entity);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }

    /**
     * 修改一个方案关联的人员信息
     *
     * @param inventoryId 方案ID
     * @param extId       关联ID
     * @param extEntity   接收的数据
     * @return
     */
    @PutMapping("{extId}")
    public Object update(@PathVariable String inventoryId, @PathVariable String extId, @RequestBody MaterialinventoryMaterialExtEntity extEntity) {
        extEntity.setId(extId);
        extEntity.setMaterialinventoryId(inventoryId);
        materialinventoryMaterialExtService.updateMaterialinventoryMaterialExt(extEntity);
        return success(null);
    }

    /**
     * 盘点校正
     * @param inventoryId
     * @param extId
     * @param extEntity
     * @return
     */
    @PutMapping("inventoryCorrection/{extId}")
    public Object inventoryCorrection(@PathVariable String inventoryId, @PathVariable String extId, @RequestBody MaterialinventoryMaterialExtEntity extEntity) {
        extEntity.setId(extId);
        extEntity.setMaterialinventoryId(inventoryId);
        materialinventoryMaterialExtService.inventoryCorrection(extEntity);

        return success(null);
    }

    /**
     * 删除一个 <strong>物资盘点计划与物资关系表</strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        materialinventoryMaterialExtService.deleteMaterialinventoryMaterialExt(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 删除多个 <strong>物资盘点计划与物资关系表</strong>
     *
     * @param ids 主键ID列表
     */
    @DeleteMapping
    public Object deleteIds(@RequestBody List<String> ids) {
        materialinventoryMaterialExtService.deleteMaterialinventoryMaterialExt(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<MaterialinventoryMaterialExtEntity> buildLambdaQuery(MaterialinventoryMaterialExtEntity entity) {
        LambdaQueryChainWrapper<MaterialinventoryMaterialExtEntity> lambdaQuery = materialinventoryMaterialExtService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), MaterialinventoryMaterialExtEntity::getId, entity.getId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getMaterialinventoryId()), MaterialinventoryMaterialExtEntity::getMaterialinventoryId, entity.getMaterialinventoryId());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getStorehouseId()), MaterialinventoryMaterialExtEntity::getStorehouseId, entity.getStorehouseId());
        lambdaQuery.eq(entity.getMaterialId() != null, MaterialinventoryMaterialExtEntity::getMaterialId, entity.getMaterialId());
        lambdaQuery.eq(entity.getQuantity() != null, MaterialinventoryMaterialExtEntity::getQuantity, entity.getQuantity());
        lambdaQuery.like(StringUtils.isNotBlank(entity.getUnitmeasurement()), MaterialinventoryMaterialExtEntity::getUnitmeasurement, entity.getUnitmeasurement());
        lambdaQuery.eq(entity.getInventoryquantity() != null, MaterialinventoryMaterialExtEntity::getInventoryquantity, entity.getInventoryquantity());
        lambdaQuery.eq(entity.getProfitAndLoss() != null, MaterialinventoryMaterialExtEntity::getProfitAndLoss, entity.getProfitAndLoss());
        return lambdaQuery;
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象
     * @return lambda query chain wrapper
     */
    private QueryWrapper<MaterialinventoryMaterialExtEntity> buildQuery(MaterialinventoryMaterialExtEntity entity) {
        QueryWrapper<MaterialinventoryMaterialExtEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(entity.getId()), "id", entity.getId());
        wrapper.like(StringUtils.isNotBlank(entity.getMaterialinventoryId()), "materialinventory_id", entity.getMaterialinventoryId());
        wrapper.like(StringUtils.isNotBlank(entity.getStorehouseId()), "storehouse_id", entity.getStorehouseId());
        wrapper.eq(entity.getMaterialId() != null, "material_id", entity.getMaterialId());
        wrapper.eq(entity.getQuantity() != null, "quantity", entity.getQuantity());
        wrapper.like(StringUtils.isNotBlank(entity.getUnitmeasurement()), "unitmeasurement", entity.getUnitmeasurement());
        wrapper.eq(entity.getInventoryquantity() != null, "inventoryquantity", entity.getInventoryquantity());
        wrapper.eq(entity.getProfitAndLoss() != null, "profit_and_loss", entity.getProfitAndLoss());
        return wrapper;
    }
}
